#region (c) 2009 Rinat Abdullin

// Copyright (c) Rinat Abdullin
// All Rights Reserved
// Site: http://abdullin.com

#endregion

using System;
using System.IO;
using Jayrock.Json;
using Jayrock.Json.Conversion;
using Jayrock.Json.Conversion.Converters;
using NCouch.Model;

namespace NCouch.Json
{
	public sealed class JayrockSerializer : ISerializer
	{
		readonly ExportContext _exports = new ExportContext();
		readonly ImportContext _imports = new ImportContext();

		public JayrockSerializer()
		{
			_imports.Register(new ArrayImporter(typeof(string[])));
		}

		public object Deserialize(Stream reader, Type type)
		{
			using (var text = new StreamReader(reader))
			using (var json = new JsonTextReader(text))
			{
				return _imports.Import(type, json);
			}
		}

		public void Serialize(Stream writer, Type type, object item)
		{
			using (var text = new StreamWriter(writer))
			using (var json = new JsonTextWriter(text))
			{
				var exporter = _exports.FindExporter(type);
				exporter.Export(_exports, item, json);
				//_exports.Export(item, json);
			}
		}

		public void RegisterFSharpModel(Type type)
		{
			_imports.Register(new FirstConstructorImporter(type));
			_exports.Register(new FSharpComponentExporter(type));
			//_exports.Register(new FieldExporter(type));
		}

		public void RegisterCSharpModel(Type type)
		{
			_imports.Register(new FirstConstructorImporter(type));
			_exports.Register(new FieldExporter(type));
		}

		public ViewRegistrationSyntax<TValue> RegisterCSharpData<TValue>()
		{
			var type = typeof (TValue);
			_imports.Register(new ComponentImporter(type));
			_exports.Register(new ComponentExporter(type));

			return CreateViewSyntax<TValue>();
		}

		public ViewRegistrationSyntax<TValue> CreateViewSyntax<TValue>()
		{
			return new ViewRegistrationSyntax<TValue>(t => _imports
				.Register(new FirstConstructorImporter(t)));
		}
	}
}